package svc

import (
	"context"
	"fmt"
	"log"
	"usercenter/internal/config"
	"usercenter/internal/middleware"
	"usercenter/internal/model"
	"usercenter/internal/utils"
	"usercenter/internal/verification"

	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
	"github.com/zeromicro/go-zero/core/stores/redis"
	"github.com/zeromicro/go-zero/rest"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type ServiceContext struct {
	Config          config.Config
	DB              *gorm.DB
	Redis           *redis.Redis
	VerificationMgr *verification.VerificationManager
	EmailServer     *verification.EmailService
	UserModel       model.UserModel
	Auth            rest.Middleware
	MinioClient     *minio.Client // 添加 Minio/S3 客户端
	GorseClient     *utils.GorseClient
}

func NewServiceContext(c config.Config) *ServiceContext {
	// 初始化数据库
	db, err := gorm.Open(mysql.Open(c.DB.DataSource), &gorm.Config{})
	if err != nil {
		log.Fatal(err)
	}

	// 自动迁移 User 表
	if err := db.AutoMigrate(&model.User{}, &model.JoyImg{}); err != nil {
		log.Fatal(err)
	}

	// 初始化Redis
	rds := redis.MustNewRedis(redis.RedisConf{
		Host: c.Redis.Host,
		Pass: c.Redis.Pass,
		Tls:  c.Redis.Tls,
		Type: c.Redis.Type,
	})

	// 初始化邮件服务
	emailService := verification.NewEmailService(verification.EmailConfig{
		Host:     c.Email.Host,
		Port:     c.Email.Port,
		Username: c.Email.Username,
		Password: c.Email.Password,
		From:     c.Email.From,
	})

	// 初始化验证管理器
	verificationMgr := verification.NewVerificationManager(rds, emailService)

	// 初始化Minio客户端
	minioClient, err := minio.New(c.Minio.Endpoint, &minio.Options{
		Creds:  credentials.NewStaticV4(c.Minio.AccessKey, c.Minio.SecretKey, ""),
		Secure: c.Minio.UseSSL,
	})
	if err != nil {
		panic(fmt.Errorf("初始化Minio客户端失败: %v", err))
	}

	// 检查存储桶是否存在，不存在则创建
	ctx := context.Background()
	exists, err := minioClient.BucketExists(ctx, c.Minio.BucketName)
	if err != nil {
		panic(fmt.Errorf("检查存储桶失败: %v", err))
	}
	if !exists {
		err = minioClient.MakeBucket(ctx, c.Minio.BucketName, minio.MakeBucketOptions{})
		if err != nil {
			panic(fmt.Errorf("创建存储桶失败: %v", err))
		}
	}

	return &ServiceContext{
		Config:          c,
		DB:              db,
		Redis:           rds,
		VerificationMgr: verificationMgr,
		EmailServer:     emailService,
		UserModel:       model.NewUserModel(db),
		Auth:            middleware.NewAuthMiddleware(c.JWT.AccessSecret),
		MinioClient:     minioClient,
		GorseClient:     utils.NewGorseClient(c.Gorse.Host, c.Gorse.ApiKey),
	}
}
